/**
 * 
 */
package com.hexacta.hrs.report.managers;

import java.io.ByteArrayOutputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.vectrics.common.util.DateUtil;
import org.vectrics.employee.Employee;

import com.hexacta.hrs.report.AbstractReport;
import com.hexacta.hrs.report.dtos.GeneralTimeOffReportDTO;
import com.hexacta.hrs.services.employee.EmployeeService;
import com.hexacta.hrs.services.timeoff.TimeOffService;
import com.hexacta.hrs.timeoff.Status;
import com.hexacta.hrs.timeoff.TimeOff;
import com.hexacta.hrs.timeoff.TimeOffStatusDetail;
import com.hexacta.hrs.timeoff.TimeOffType;

/**
 * @author iandronowicz clase que genera el reporte general de timeoff
 */
public class GeneralTimeOffReport extends AbstractReport {

    private EmployeeService employeeService;

    private TimeOffService timeOffService;

    /**
     * @return the employeeService
     */
    public EmployeeService getEmployeeService() {
        return employeeService;
    }

    /**
     * @param employeeService
     *            the employeeService to set
     */
    public void setEmployeeService(final EmployeeService employeeService) {
        this.employeeService = employeeService;
    }

    /**
     * @return the timeOffService
     */
    public TimeOffService getTimeOffService() {
        return timeOffService;
    }

    /**
     * @param timeOffService
     *            the timeOffService to set
     */
    public void setTimeOffService(final TimeOffService timeOffService) {
        this.timeOffService = timeOffService;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    @SuppressWarnings("unchecked")
    protected Collection getReportData(final Map<String, Object> filters) {
        Collection<GeneralTimeOffReportDTO> collection = new ArrayList<GeneralTimeOffReportDTO>();

        TimeOff criteria = new TimeOff();

        if (filters != null) {

            if (filters.containsKey("selectedTimeOffType")) {
                criteria.setTimeOffType(TimeOffType.valueOf((String) filters.get("selectedTimeOffType")));
            }
            if (filters.containsKey("selectedEmployeeId")) {
                criteria.setEmployee(employeeService.searchById(Long.valueOf((String) filters.get("selectedEmployeeId"))));
            }
            if (filters.containsKey("selectedDateFrom")) {
                criteria.setDateFrom((Date) filters.get("selectedDateFrom"));
            }
            if (filters.containsKey("selectedDateTo")) {
                criteria.setDateTo((Date) filters.get("selectedDateTo"));
            }
            if (filters.containsKey("selectedStatus")) {
                TimeOffStatusDetail timeOffStatusDetail = new TimeOffStatusDetail();
                timeOffStatusDetail.setStatus(Status.valueOf((String) filters.get("selectedStatus")));
                criteria.addNewStatus(timeOffStatusDetail);
            }

        }

        Collection<Employee> noLongerEmpList = employeeService.getNoLongerEmployees();
        Collection<TimeOff> timeOffCollection = timeOffService.searchByCriteria(criteria);
        for (TimeOff timeOff : timeOffCollection) {
            if (!noLongerEmpList.contains(timeOff.getEmployee())) {
                GeneralTimeOffReportDTO dto = new GeneralTimeOffReportDTO();
                dto.setEmployeeName(timeOff.getEmployee().getPerson().getLastName() + ", "
                        + timeOff.getEmployee().getPerson().getFirstName());
                dto.setTimeOffType(timeOff.getTimeOffType().name().replaceAll("_", " "));
                dto.setStatus(timeOff.getCurrentStatusType().name());
                dto.setDateFrom(DateUtil.getFechaFormateada(timeOff.getDateFrom()));
                dto.setDateTo(DateUtil.getFechaFormateada(timeOff.getDateTo()));
                dto.setTotalDays(String.valueOf(DateUtil.getDaysBetween(timeOff.getDateFrom(), timeOff.getDateTo())));
                // dto.setTotalDays(DateUtil.getDaysBetween(timeOff.getDateFrom(),
                // timeOff.getDateTo()));
                // Si NO es una de estas: VACACIONES,EXAMEN,PERIODO_COMPENSADO,
                // sumo tambien sabados y domingos

                // if (timeOff.getTimeOffType() != TimeOffType.VACACIONES
                // && timeOff.getTimeOffType() != TimeOffType.EXAMEN
                // && timeOff.getTimeOffType() !=
                // TimeOffType.PERIODO_COMPENSADO) {
                // dto.setTotalDays(String
                // .valueOf(DateUtil.getDaysBetween(timeOff.getDateFrom(),
                // timeOff.getDateTo())));
                // } else {
                // dto.setTotalDays(String.valueOf(DateUtil.getWorkingDaysBetween(timeOff.getDateFrom(),
                // timeOff
                // .getDateTo())));
                // }
                collection.add(dto);
            }
        }

        if (collection.isEmpty())
            throw new RuntimeException("There is no data for this report");

        Collections.sort((List) collection);

        return collection;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    @SuppressWarnings("unchecked")
    protected Map getReportParameters() {
        // TODO Auto-generated method stub
        return null;
    }

    /** {@inheritDoc} */
    public ByteArrayOutputStream createPDFReport(final String reportName, final String reportTemplateLocation,
            final Map<String, Object> filters, final Map<String, Object> parameters) {
        return createPDF(reportTemplateLocation, parameters, getReportData(filters));
    }

    /*
     * (non-Javadoc)
     * 
     * @see com.hexacta.hrs.report.Report#createXLSReport(java.lang.String,
     * java.lang.String)
     */
    public ByteArrayOutputStream createXLSReport(final String reportName, final String reportTemplateLocation,
            final Map<String, Object> filters, final Map<String, Object> parameters) {
        return createExcel(reportTemplateLocation, parameters, getReportData(filters));
    }
}
